home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / sharew / emulator / c64 / artikel.txt < prev    next >
Text File  |  1994-10-17  |  22KB  |  384 lines

  1. Wohl jeder, der sich etwas intensiver mit seinem Computer 
  2. beschäftigt hat, wird sich schon einmal geärgert haben, daß 
  3. ausgerechnet das Programm, das er gerne besitzen würde, auf 
  4. seinem Rechner nicht läuft. Besonders viel professionelle 
  5. Software ist z.B. für andere Betriebssysteme wie MS-DOS oder CP/M 
  6. zu erhalten. Da diese Systeme jedoch für andere Prozessoren als 
  7. den 68000 geschrieben sind, ist es eigentlich nicht möglich, 
  8. deren Programme auf dem Atari ST zu verwenden. Ganz ausweglos ist 
  9. die Situation nun aber auch nicht. Für die oben genannten 
  10. Betriebssysteme gibt es inzwischen Emulatoren auf dem Markt, die 
  11. es ermöglichen, auch Programme, die für andere Prozessoren oder 
  12. Betriebssysteme geschrieben worden sind, auf dem ST laufen zu 
  13. lassen. Von diesen Programmen sind die MAC-Emulatoren besonders 
  14. hervorzuheben. Da der Macintosh wie der ST ebenfalls mit einen 
  15. 68000-Prozessor arbeitet, ist es in diesem Fall möglich, durch 
  16. ein entsprechendes Programm nicht nur das Macintosh-
  17. Betriebssystem auf dem ST zu implementieren, sondern dabei auch 
  18. noch eine größere Geschwindigkeit im Programmablauf zu erreichen, 
  19. als dies auf dem "Original" MAC-System der Fall ist. Die Ursache 
  20. hierfür liegt darin, daß der 68000 beim ST höher getaktet ist, 
  21. als im Macintosh. Leider dürfte diese Art von Emulatoren ein 
  22. Sonderfall bleiben, denn die bekanntesten Betriebssysteme laufen 
  23. nun einmal nur auf Rechnern, die keinen Prozessor der 68000-
  24. Familie benutzen. In diesem Fall bleibt als Ausweg nur die 
  25. Software-Emulation des entsprechenden Prozessors. Der 
  26. Geschwindigkeitsverlust, der dabei auftritt, läßt sich leider 
  27. nicht vermeiden. Allerdings kann man bei entsprechender 
  28. Programmierung trotzdem recht akzeptable Geschwindigkeiten 
  29. erreichen, auch wenn man dieses nicht jedem auf dem Markt 
  30. befindlichen Emulator anmerkt.
  31. Als Atari- und C64-Besitzer habe ich mich damit beschäftigt, das 
  32. Betriebssystem des C64 so gut wie möglich auf dem ST zu 
  33. implementieren. Für die Spiele-Freaks heißt das aber leider 
  34. nicht, daß nun der ST in der Lage ist, C64-Spiele zu verarbeiten. 
  35. Dazu ist der Aufbau der beiden Computer zu verschieden. Dennoch 
  36. läßt sich bis auf einige spezielle Fähigkeiten des C64 ein 
  37. brauchbarer Emulator entwickeln. Was man bei der Programmierung 
  38. eines solchen Emulatorprogramms beachten sollte, wird Gegenstand 
  39. des Artikels sein. Da dieser Teil Kenntnisse in Assembler-
  40. Programmierung voraussetzt, dürfte er vor allem für Assembler-
  41. Programmierer interessant sein. Außerdem möchte ich kurz ein paar 
  42. Features des C64-Emulators beschreiben. Konkretere Hinweise 
  43. finden sich auf der Leserservice-Diskette, auf der sich der 
  44. Emulator befindet.
  45. Bevor man sich um die Implementierung eines konkreten 
  46. Betriebssystems kümmern kann, geht es erst einmal darum, sich 
  47. detaillierte Informationen über den zu emulierenden Prozessor zu 
  48. besorgen. (Dabei setze ich natürlich voraus, daß man die 
  49. Programmierung des 68000 gut beherrscht.) Um sich näher mit dem 
  50. eigentlichen Betriebssystem beschäftigen zu können, muß 
  51. schließlich erst einmal die Emulation für den entsprechenden 
  52. Prozessor stehen. Für die bekanntesten Prozessoren, wie im Fall 
  53. des C64 für den 6502, ist es kein Problem, an die entsprechende 
  54. Literatur zu kommen. Wichtig sind vor allem Informationen über 
  55. die Behandlung der Flags des Prozessors bei den verschiedenen 
  56. Befehlstypen sowie eine Beschreibung eventueller Besonderheiten 
  57. des Prozessors. Zu beachten ist, daß z.B. das Carry-Flag durchaus 
  58. nicht in allen Prozessoren die gleiche Bedeutung hat. Gerade der 
  59. 6502 hat hier seine Besonderheit. Im günstigsten Fall hat man 
  60. schon einmal mit dem zu emulierenden Prozessor gearbeitet, was 
  61. sich im weiteren Verlauf der Programmierung als großer Vorteil 
  62. erweisen wird.
  63. Bei der eigentlichen Programmierung des Emulators spielt die 
  64. Geschwindigkeit der Befehlsauswertung eine besonders große Rolle. 
  65. Da der 68000 mit den Befehlscodes des 6502 überhaupt nichts 
  66. anfangen kann, muß jeder Opcode interpretiert werden, ähnlich wie 
  67. es ein BASIC-Interpreter mit einem BASIC-Programm macht. Für 
  68. jeden 6502-Code muß eine Routine in 68000-Assembler entwickelt 
  69. werden, die Aktionen vornimmt, die dem entsprechenden 6502-Befehl 
  70. entsprechen. Hierin liegt auch der Grund, warum es nicht möglich 
  71. ist, mit einem Software-Emulator die gleiche Geschwindigkeit zu 
  72. erreichen, wie sie das System besitzt, das emuliert wird. Obwohl 
  73. der 68000 mit 8 MHz getaktet ist und der 6510 im C64 mit nur 
  74. knapp 1 MHz, bedeutet die Interpretation der Befehlsbytes einen 
  75. Verlust an Geschwindigkeit. Die eigentliche Bearbeitung der 
  76. einzelnen Opcodes in den entsprechenden Routinen kann jedoch 
  77. durchaus schneller vom 68000 ausgeführt werden, als vom 6502. So 
  78. benötigt der C64-Emulator zum Setzen des Carry-Flags 4 Taktyklen, 
  79. der 6502 braucht 2 Taktzyklen. Rechnet man diese Angaben auf die 
  80. Taktfrequenzen der beiden Prozessoren um, so schneidet der 68000 
  81. deutlich besser ab. Allerdings muß nun noch die Zeit addiert 
  82. werden, die der Emulator benötigt, bis er die Adresse der Routine 
  83. zum Setzen des Flags ermittelt hat. Dieser Vorgang nimmt jedoch 
  84. so viel Zeit in Anspruch, daß der 6502 schließlich doch der 
  85. Schnellere ist. Da die Taktfrequenz neuerer Prozessortypen immer 
  86. weiter steigt, wird es wohl nur eine Frage der Zeit sein, bis es 
  87. möglich ist, einen 8 Bit-Prozessor mindestens mit der 
  88. Geschwindigkeit zu emulieren, mit der dieser Prozessor 
  89. normalerweise betrieben wird.
  90. Nun wiederholt sich der Vorgang der Interpretation des folgenden 
  91. Befehlsbytes natürlich bei jedem neuen 6502-Opcode. Deshalb ist 
  92. es gerade an dieser Stelle besonders wichtig, eine möglichst 
  93. schnelle Auswertung des nächsten Befehlsbytes zu erreichen. Spart 
  94. man hier nur einen Taktzyklus ein, so steigt die Geschwindigkeit 
  95. der Emulation bereits merklich. Wie kann nun das nächste 
  96. Befehlsbyte ausgewertet werden? Im allgemeinen wird hierzu dieses 
  97. Byte in ein Datenregister geladen und dann die Adresse der 
  98. zugehörigen Emulationsroutine aus diesem Byte berechnet. Dies 
  99. kann z.B. durch den folgenden Algorithmus geschehen:
  100.  
  101. LOOP:  CLR D0
  102.        MOVE.B (A0)+,D0
  103.        ASL #2,D0
  104.        MOVE.L (A1,D0),A0           Algorithmus 1
  105.        JSR (A0)
  106.        BRA LOOP
  107.  
  108. Geht man davon aus, daß A0 auf das nächste Befehlsbyte im 6502-
  109. Adreßraum zeigt und A1 den Anfang einer Tabelle mit 
  110. Sprungadressen auf die entsprechenden Emulationsroutinen enthält, 
  111. würde obiges Programmfragment den Anforderungen gerecht. 
  112. Allerdings läßt die Geschwindigkeit der Interpretation noch viel 
  113. zu wünschen übrig. Um eine höhere Geschwindigkeit zu erreichen, 
  114. kann man den ASL-Befehl durch zwei ADD-Befehle ersetzen und die 
  115. obige Routine für jeden zu emulierenden Opcode neu programmieren, 
  116. was dann so aussehen könnte:
  117.  
  118.        CLR D0
  119.        MOVE.B (A0)+,D0
  120.        ADD D0,D0
  121.        ADD D0,D0
  122.        MOVE.L (A1,D0),A0           Algorithmus 2
  123.        JMP (A0)
  124.  
  125. In diesem Fall wird die nächste auszuführende Routine nicht mehr 
  126. als Unterprogramm angesprungen, so daß man nicht mit RTS zu einer 
  127. übergeordneten Interpretationsroutine zurückkehren kann. Eben aus 
  128. diesem Grund muß sich der obige Programmteil am Ende jeder 
  129. Emulations-Unterroutine befinden, also für jeden Opcode einmal im 
  130. Programm vorhanden sein. Dadurch wird das Emulatorprogramm zwar 
  131. länger, dafür aber deutlich schneller, da der Aufruf und die 
  132. Rückkehr aus einem Unterprogramm besonders viel Zeit benötigt. 
  133. Und Geschwindigkeit ist für einen Software-Emulator das höchste 
  134. Gebot! Darüber hinaus hat man auf dem ST genug Speicherplatz, um 
  135. bei einem Emulator für einen Prozessor mit nur 64K Adreßraum 
  136. nicht sparen zu müssen.
  137. Der oben dargestellte Algorithmus 2 findet sich in ähnlicher Form 
  138. in allen mir bekannten Software-Emulatoren wieder. Lassen sie uns 
  139. einmal ein wenig rechnen: Die Ausführungsgeschwindigkeit für 
  140. diesen Algorithmus beträgt 46 Taktzyklen. Der 6502 ist 
  141. normalerweise mit 1MHz getaktet, der ST mit 8MHz. Allein die 
  142. Interpretation eines Befehlsbytes würde demnach eine Zeit 
  143. verbrauchen, die 46/8 6502-Zyklen entspricht, also fast 6 6502-
  144. Zyklen. Da die kürzesten 6502-Befehle 2 Taktzyklen (bezogen auf 
  145. den 6502) brauchen, würde nur die Auswertung des nächsten Befehls 
  146. durch den Emulator schon extrem viel Zeit verschlingen. Das 
  147. Prinzip, das in Algorithmus 2 zur Interpretation verwendet wurde, 
  148. kann jedoch nicht mehr entscheidend verkürzt werden. Ursprünglich 
  149. arbeitet auch mein C64-Emulator mit einem vergleichbaren 
  150. Algorithmus.
  151. Ist man allerdings bereit, 64K Speicherplatz mehr für den 
  152. Emulator zu opfern, was beim ST normalerweise möglich ist, so 
  153. kann man die so zeitkritische Befehlsinterpretation durch eine 
  154. völlig andere Programmierung deutlich beschleunigen. Hier die 
  155. Routine, wie sie in meinem Emulator verwendet wird:
  156.  
  157.        MOVE.B (A0)+,LBL+2(A1)
  158. LBL:   JMP $0(A1)             Algorithmus 3
  159.  
  160. Auch hier ist A0 Pointer auf das nächste Befehlsbyte, A1 ist ein 
  161. spezieller Pointer in das 64K-Segment, in dem sich der Emulator 
  162. nun befindet. Nun ein paar Erklärungen zu Algorithmus 3, denn er 
  163. dürfte nicht so einsichtig sein, wie die ersten beiden. Im obigen 
  164. Fall wird das Befehlsbyte nämlich ohne irgendwelche weiteren 
  165. Berechnungen direkt zur Adreßbildung im darauffolgenden 
  166. Sprungbefehl verwendet. Hierzu am besten ein Beispiel. Nehmen wir 
  167. an, der nächste 6502-Opcode, auf den das Adreßregister A0 zeigt, 
  168. ist $EA. Dieses Byte wird nun als Displacement für den folgenden 
  169. Sprungbefehl benutzt, wobei sich das Programm selbst verändert. 
  170. Direkt vor dem Sprung sieht der Sprungbefehl dann also 
  171. folgendermaßen aus:
  172.  
  173.        JMP $EA00(A2)
  174.  
  175. Das 6502-Befehlsbyte bildet das Hi-Byte für das Displacement, das 
  176. Lo-Byte ist immer Null. Auf diese Art und Weise spart man sich 
  177. jegliche Adreßberechnung, da die Sprungadresse auf die passende 
  178. Routine nicht mehr einer Tabelle entnommen wird, wie es bei den 
  179. ersten beiden Algorithmen der Fall ist. Allerdings muß nun jede 
  180. Routine zur Behandlung der Opcodes in genau einer Page Abstand 
  181. hinter dem Beginn der vorherigen Routine anfangen, da das Lo-Byte 
  182. des Displacements immer Null ist. So kommt es auch, das für diese 
  183. Art der Emulation 64K Speicherplatz benötigt werden, nämlich für 
  184. jeden Opcode des 6502 256 Bytes. Die Ausführungszeit von 
  185. Algorithmus 3 beträgt nur noch 30 Taktzyklen. Er ist also um 50% 
  186. schneller als Algorithmus 2. Dieser Geschwindigkeitszuwachs macht 
  187. sich deutlich bemerkbar, denn er schlägt ja bei jedem 6502-Opcode 
  188. neu zu Buche.
  189. Soweit das Wichtigste zur Interpretation der Befehlsbytes des 
  190. 6502. Ist dieses Problem gelöst, so muß man sich als Nächstes 
  191. darum kümmern, wo die Register des zu emulierenden Prozessors 
  192. "aufbewahrt" werden können. In unserem Fall ist diese Frage recht 
  193. einfach zu beantworten. Der 6502 hat drei Register (Akkumulator, 
  194. X- und Y-Register) sowie einen 8-Bit-Stackpointer und den 
  195. Programmzähler. Der 68000 besitzt insgesamt 15 Register, wenn man 
  196. A7 als Stackpointer einmal außer Acht läßt. Es ist somit keine 
  197. Kunst, diese Register in Daten- bzw. Adreßregistern des 68000 
  198. unterzubringen. Für Stackpointer und Programmzähler wird jeweils 
  199. ein Adreßregister, für die anderen 6502-Register werden drei 
  200. Datenregister verwendet, in denen nur das Lo-Byte genutzt wird. 
  201. Schließlich muß das Prozessorstatusregister des 6502 auch noch 
  202. irgendwo untergebracht werden. Es ist im allgemeinen nicht 
  203. möglich, einfach die Flags des 68000 zu verwenden, da sich deren 
  204. Verwendung von der beim 6502 geringfügig unterscheidet. Darüber 
  205. hinaus hat der 68000 im Gegensatz zum 6502 z.B. kein Dezimalflag. 
  206. Bei den meisten arithmetischen Operationen besteht in der 
  207. Behandlung der Flags jedoch kein Unterschied. Es empfiehlt sich, 
  208. die Flags in einem weiteren Datenregister unterzubringen und nur 
  209. bei Bedarf in das CCR-Register des 68000 zu übertragen. 
  210. Schließlich wird des Prozessorstatusregister nicht von jedem 
  211. Befehl beeinflußt. Nachdem bei Rechenoperationen die Flags im CCR 
  212. entsprechend gesetzt worden sind, werden sie dann wieder in das 
  213. reservierte Datenregister übertragen.
  214. Durch die beschriebene Verwendung der Register bleiben noch 
  215. einige Register dem Programmierer zur Verfügung. Sie können dann 
  216. Daten aufnehmen, die während der Emulation ständig zur Verfügung 
  217. stehen sollen, wie z.B. ein Pointer auf den 64K Adreßraum des 
  218. 6502 sowie auf die 64K, die für den Emulator reserviert sind, und 
  219. in dem sich die Emulationsroutinen für die einzelnen Opcodes des 
  220. 6502 befinden. Prinzipiell ist es natürlich auch möglich, die 
  221. Registerinhalte des 6502 im Speicher abzulegen. Allerdings dauern 
  222. Zugriffe auf den Speicher verhältnismäßig lange, so daß man keine 
  223. brauchbare Geschwindigkeit mehr erzielen könnte.
  224. Will man Prozessoren emulieren, die mehr Register aufweisen, als 
  225. der 6502 sie besitzt, so muß man die Aufteilung neu überdenken. 
  226. Dies ist übrigens bei den meisten anderen Prozessoren der Fall, 
  227. z.B. beim 8080, Z80 und 8086. Man sollte jedoch durch geschickte 
  228. Wahl der Registerbelegung stets dafür sorgen, daß absolute 
  229. Zugriffe auf den Speicher möglichst vermieden werden, da sie 
  230. besonders zeitaufwendig sind. Beim C64-Emulator konnten direkte 
  231. Zugriffe auf den Speicher vollkommen umgangen werden. Hier wird 
  232. nur über Adreßregister auf den Adreßraum des 6502-Prozessors 
  233. zugegriffen.
  234. Will man mit dem 68000 einen 8 Bit-Prozessor emulieren, so sind 
  235. einige Adressierungsarten und Befehle recht leicht 
  236. nachzuvollziehen, andere stellen jedoch Probleme dar, besonders 
  237. dann, wenn es darum geht, eine möglichst schnelle Ausführungszeit 
  238. zu erzielen. Ich möchte hier als Beispiel die absolute 
  239. Adressierung des 6502 anführen. Eigentlich kein Problem, sollte 
  240. man meinen. Aber dennoch muß man hier vorsichtig sein. Wie sie 
  241. sicher wissen, kann der 68000 auf 16 Bit-Worte nur dann 
  242. zugreifen, wenn sie auf geraden Speicheradressen stehen. Verstöße 
  243. gegen diese Regel führen zu einem Adreßfehler, der sich in drei 
  244. Bomben personifiziert. Bei Programmen, die für diesen Prozessor 
  245. geschrieben sind, liegen die Befehlsworte und absoluten Adressen 
  246. deshalb natürlich immer auf geraden Adressen. Bei 8 Bit 
  247. Prozessoren sieht die Sache jedoch ganz anders aus. Die oben 
  248. angeführte Einschränkung für absolute Adressen besteht hier 
  249. nicht. Es kann also ohne Weiteres passieren, daß die absolute 
  250. Adresse, die auf einen Sprungbefehl des 6502 folgt, auf einer 
  251. ungeraden Adresse liegt. Somit ist es nicht möglich, die Adressen 
  252. für die absolute Adressierung mit einem einzigen Befehl aus dem 
  253. 6502-Adreßraum in ein Register des 68000  zu holen. Solche 
  254. Adressen müssen hier grundsätzlich in zwei einzelne Bytes 
  255. aufgespalten werden. Darüber hinaus existiert noch ein weiteres 
  256. Ärgernis. Im Gegensatz zum 68000 werden bei 8 Bit Prozessoren 
  257. absolute Adressen mit den Lo-Byte zuerst im Speicher abgelegt. 
  258. Bevor man eine solche Adresse verwenden kann, müssen also erst 
  259. die beiden Adreßbytes in die richtige Reihenfolge gebracht 
  260. werden. Mit folgender Routine könnte dann die absolute Adresse 
  261. aus dem Speicher in ein Datenregister geholt werden:
  262.  
  263.        MOVE.B (A0)+,D0
  264.        ASL #8,D0              Algorithmus 4
  265.        MOVE.B (A0)+,D0
  266.        ROR #8,D0
  267.  
  268. Die beiden Bytes für die absolute Adresse werden hier einzeln aus 
  269. dem Speicher geholt und durch Schieben und Rotieren in die 
  270. richtige Reihenfolge gebracht. So weit, so gut. Leider brauchen 
  271. Schiebe- und Rotierbefehle relativ viel Zeit. Algorithmus 4 mag 
  272. zwar leicht zu durchschauen sein, benötigt jedoch 58 Taktzyklen. 
  273. Dies ist besonders ungünstig, wenn man bedenkt, daß die absolute 
  274. Adressierung relativ häufig vorkommt. Ist man jedoch bereit, ein 
  275. Adreßregister zu opfern, so kann man durch eine völlig 
  276. andersartige Programmierung einen großen Geschwindigkeitsvorteil 
  277. erlangen:
  278.  
  279.        MOVE.B (A0)+,-(A2)
  280.        MOVE.B (A0)+,-(A2)     Algorithmus 5
  281.        MOVE (A2)+,D0
  282.  
  283. In Algorithmus 5 zeigt A2 auf eine beliebige gerade Adresse im 
  284. Speicher, an der die beiden Bytes zu einem Wort zusammengesetzt 
  285. und anschließend nach D0 übertragen werden. Diese etwas 
  286. unkonventionelle Art der Programmierung mag zwar umständlich 
  287. erscheinen, sie kommt dafür jedoch mit nur 32 Zyklen aus, denn 
  288. Schiebe- und Rotierbefehle entfallen nun völlig. Leider ist es 
  289. nicht möglich, den Stackpointer, also A7, so zu benutzen, wie in 
  290. diesem Beispiel A2. Der Stackpointer wird nämlich grundsätzlich 
  291. um ein Wort, also zwei Bytes, erhöht oder erniedrigt, auch wenn 
  292. Byteoperationen durchgeführt werden, so daß er sich nicht an 
  293. Stelle eines anderen Adreßregisters benutzen läßt.
  294. Die obige Problematik stellt nur eines von vielen Problemen dar, 
  295. die man bei der Emulation eines 8 Bit Prozessors zu bewältigen 
  296. hat, wenn man um jeden Taktzyklus kämpfen muß.
  297. Ist nun endlich die eigentliche Emulation des Prozessors 
  298. fertiggestellt, wobei natürlich fraglich ist, wieviele Fehler sie 
  299. noch enthält, muß man als nächstes sein Augenmerk auf die 
  300. Implementation des Betriebssystems richten. Schließlich ist es 
  301. das erste und wichtigste Programm, das man zum Laufen bringen 
  302. muß. Läuft das Betriebssystem unter dem Emulator einwandfrei, so 
  303. kann man davon ausgehen, daß sich kaum noch Fehler im Programm 
  304. befinden, da alle Befehle des emulierten Prozessors irgendwann 
  305. einmal ausgeführt werden dürften.
  306. Nicht jedes Betriebssystem läßt sich gleich gut auf einen anderen 
  307. Computer übertragen. Das Betriebssystem des C64 läßt in dieser 
  308. Hinsicht einiges zu Wünschen übrig. Im günstigsten Fall gibt es 
  309. für jede wichtige Funktion, die vom System erledigt werden soll, 
  310. also insbesondere um die Behandlung der Ein- und Ausgabe, eine 
  311. Funktionsnummer oder einen Sprungvektor. Beim C64 gibt es zwar 
  312. eine solche Liste von Sprungvektoren, nur ist sie leider nicht so 
  313. vollständig, wie man es gerne hätte. Besser sieht es da bei CP/M 
  314. und MS-DOS aus. Hier gibt es weitaus mehr Funktionen als beim 
  315. C64, so daß eine Emulation erleichtert wird. Dies liegt natürlich 
  316. daran, daß diese beiden System ohnehin für den Einsatz auf 
  317. unterschiedlichen Computern vorgesehen sind, was beim C64 ja 
  318. nicht unbedingt der Fall ist. Welches System man auch immer 
  319. emulieren will, alle Aufgaben die über solche Vektoren oder 
  320. Funktionsnummern aufgerufen werden, müssen vom Emulator überwacht 
  321. werden. Hierzu ein konkretes Beispiel: Für die Ausgabe von 
  322. Zeichen auf dem C64 existiert ein Sprungvektor BSOUT. Da die 
  323. Bildschirmdarstellung der Zeichen auf dem ST grundsätzlich anders 
  324. realisiert wird als auf dem C64, muß an dieser Stelle 
  325. eingegriffen werden. Die Ausgabe auf dem Bildschirm darf nicht so 
  326. erfolgen, wie es beim C64 geschehen würde, denn dann würde sich 
  327. auf dem Bildschirm des ST gar nichts tun. Sie muß in einer 
  328. eigenen Ausgaberoutine programmiert werden. Das gleiche gilt für 
  329. viele andere Funktionen des Betriebssystems auf dem C64. 
  330. Natürlich muß man darauf achten, daß die Register, die für den 
  331. Betrieb des Emulators wichtige Daten enthalten, nicht in den 
  332. eigenen Routinen verändert werden bzw. nur Daten erhalten, die 
  333. vom Betriebssystem des C64 erwartet werden. Die LOAD-Routine soll 
  334. z.B. das Ende des geladenen Programms als Rückgabewert in den 
  335. Indexregistern liefern.
  336. Wie schon angesprochen, muß die Emulation durch geeignete 
  337. Programmierung so gestaltet werden, daß sie möglichst schnell 
  338. erfolgt. Neben entsprechender Programmierung des Emulators gibt 
  339. es noch weitere Möglichkeiten, die Geschwindigkeit von Programmen 
  340. auf dem ST zu erhöhen, besonders dann, wenn es sich nicht um 
  341. Programme handelt, die in GEM-Umgebung laufen. In diesem Fall ist 
  342. es nämlich möglich, Vektoren, wie den evnt_timer-Vektor des GEM 
  343. auf einen RTS-Befehl umzubiegen, so daß die zugehörigen Routinen, 
  344. die während eines Interrupts ausgeführt werden, nicht mehr 
  345. angesprungen werden. Dies hat unter anderem zur Folge, daß die 
  346. Uhr des Kontrollfelds nicht mehr läuft, wenn der Emulator aktiv 
  347. ist. Da man sie beim C64-Emulator ohnehin nicht benötigt, ist 
  348. dies aber kein Beinbruch. Der Lohn dafür ist eine erhöhte 
  349. Geschwindigkeit. Weiterhin kann es lohnenswert sein, die Maus 
  350. abzuschalten, oder besser noch alle Aktionen, die den 
  351. Tastaturprozessor betreffen, selbst zu übernehmen.
  352. Zum Schluß möchte ich noch auf die Frage eingehen, inwieweit 
  353. überhaupt eine Kompatibilität, insbesondere zum C64, auf einem 
  354. anderen Computer zu erreichen ist. Überlegt man sich, was den C64 
  355. so erfolgreich gemacht hat, so sind dies in erster Linie die 
  356. unzähligen Spiele, die für diesen Computer existieren. Gerade 
  357. Spiele reizen die speziellen Fähigkeiten des C64 (Sprites, 
  358. Rasterzeilen-Interrupt, Timer) besonders aus. Da die Hardware des 
  359. ST keine Darstellung von Sprites erlaubt, und diese Grafikobjekte 
  360. nicht nur aus Zeitgründen unmöglich durch Software nachgebildet 
  361. werden können, ist die Emulation von Spielen also in Frage 
  362. gestellt. Weiterhin ist es aus Zeitgründen nicht möglich, die 
  363. Interruptroutinen des C64 durch den Emulator ausführen zu lassen, 
  364. da dann die Arbeitsgeschwindigkeit merklich nachlassen würde. 
  365. Schließlich sind gerade Interrupts eine besonders zeitkritische 
  366. Angelegenheit, da sie sehr häufig auftreten.
  367. Damit sind nun aber alle wesentlichen Einschränkungen bei der 
  368. Emulation aufgeführt. Ein Großteil der Programme, die nicht auf 
  369. die genannten Möglichkeiten zurückgreifen, kann vom C64-Emulator 
  370. verarbeitet werden. Auch hochauflösende Grafik ist in einem 
  371. gewissen Maße möglich. Allerdings muß die Bitmap für die Grafik 
  372. im Bereich von $E000-$FFFF, also unter dem Betriebssystem liegen, 
  373. damit der Emulator erkennt, wann der Grafikspeicher angesprochen 
  374. wird. Da die Überprüfung des Bildschirmspeichers und der Bitmap 
  375. relativ viel Zeit in Anspruch nimmt, hat ein Verzicht auf diese 
  376. Ausgabekontrolle eine weitere Erhöhung der Geschwindigkeit zur 
  377. Folge.
  378. Neben der Emulation des C64 sind auch eine Drucker- und eine 
  379. Floppy-Emulation, die der 1541 weitgehend entspricht, im Emulator 
  380. enthalten. Das Programm läuft übrigens in niedriger und in hoher 
  381. Auflösung, so daß jeder ST-Besitzer sich nun seinen eigenen C64 
  382. von Disk laden kann.
  383.  
  384.